using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace LabyrinthProject
{
    public enum GraphicStyle
    {
        Green,
        Blue,
        Red,
        Dungeon
    }



    /// <summary>
    /// This is the main type for your gameh
    /// </summary>
    public class LabyrinthGame : ScreenManager.Screen
    {
        #region Constants
        const float POWERUP_HEIGHT = 0.8f;
        #endregion
        #region fields
        public static GraphicsDevice GDevice;

        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        KeyboardState lastKeyboardState = new KeyboardState();
        KeyboardState currentKeyboardState = new KeyboardState();

        List<AI> listOfAI;
        List<PowerUp> listOfPowerUps;

        private Player player1;
        private Player player2;

        Coockie coockie;
        Cupavci cupavci;

        Camera cameraPlayer1;
        Camera cameraPlayer2;

        MiniMap miniMap;
        Hud hud;
        Labyrinth labyrinth;

        Viewport viewportPlayer1;
        Viewport viewportPlayer2;

        List<Camera> listOfCameras;
        List<IDrawable> listOfDrawables;

        //Set the sound effects to use
        int soundIntensity;

        public int SoundIntensity
        {
            get { return soundIntensity; }
            set { soundIntensity = value; }
        }
        bool useSoundEffects;

        public bool UseSoundEffects
        {
            get { return useSoundEffects; }
            set { useSoundEffects = value; }
        }
        SoundEffect soundNoJump;
        SoundEffectInstance soundNoJumpInstance;
        SoundEffect soundLightsOut;
        SoundEffectInstance soundLightsOutInstance;
        SoundEffect soundLightsOut2;
        SoundEffectInstance soundLightsOut2Instance;
        SoundEffect soundNoMove;
        SoundEffectInstance soundNoMoveInstance;
        SoundEffect soundCompass;
        SoundEffectInstance soundCompassInstance;
        SoundEffect soundConfused;
        SoundEffectInstance soundConfusedInstance;
        SoundEffect soundGameEnd;
        SoundEffectInstance soundGameEndInstance;
        // music
        bool useMusic;

        public bool UseMusic
        {
            get { return useMusic; }
            set { useMusic = value; }
        }
        SoundEffect musicgame11;
        SoundEffectInstance musicgame11Instance;
        SoundEffect musicgame12;
        SoundEffectInstance musicgame12Instance;
        SoundEffect musicgame21;
        SoundEffectInstance musicgame21Instance;
        SoundEffect musicgame31;
        SoundEffectInstance musicgame31Instance;
        SoundEffect musicStolen1;
        SoundEffectInstance musicStolen1Instance;
        SoundEffect musicStolen2;
        SoundEffectInstance musicStolen2Instance;
        Queue<SoundEffectInstance> musicGameQueue;
        Queue<SoundEffectInstance> musicStolenQueue;
        SoundEffectInstance currentPlayingMusic;

        //graphic style
        GraphicStyle graphicStyle;
        Effect quadShader;
        Texture2D wallColor;
        Texture2D wallNormal;
        Texture2D groundColor;
        Texture2D groundNormal;
        Texture2D doorColor;
        Texture2D doorNormal;
        String name;

        Game game;

        bool cookiePickedUp;
        bool gotToTheEnd;
        bool almostThere = false;

        string player1model = "Models/Bacteria";
        string player2model = "Models/Bacteria";
        float player1scale = 0.5f;
        float player2scale = 0.5f;

        
        #endregion

        float upgogopl1;
        float upgogopl2;

        #region Initialize

        public LabyrinthGame(int resolutionWidth, int resolutionHeight, bool fullScreen, GraphicStyle graphicStyle,
                             bool useSoundEffects, bool useMusic, int soundIntensity, Game _game, GraphicsDeviceManager gdm)
            : base(_game.GraphicsDevice, "game")
        {

            GDevice = _game.GraphicsDevice;
            game = _game;
            graphics = gdm;
            game.Content.RootDirectory = "Content";

            graphics.PreferredBackBufferWidth = resolutionWidth;
            graphics.PreferredBackBufferHeight = resolutionHeight;
            graphics.IsFullScreen = fullScreen;

            viewportPlayer2 = new Viewport(0, 0, graphics.PreferredBackBufferWidth / 2, graphics.PreferredBackBufferHeight);
            viewportPlayer1 = new Viewport(viewportPlayer2.Width, 0, graphics.PreferredBackBufferWidth / 2, graphics.PreferredBackBufferHeight);

            musicGameQueue = new Queue<SoundEffectInstance>();
            musicStolenQueue = new Queue<SoundEffectInstance>();
            this.useSoundEffects = useSoundEffects;
            this.useMusic = useMusic;
            this.soundIntensity = soundIntensity;

            this.graphicStyle = graphicStyle;

            player1 = new Player();
            player2 = new Player();

            }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        public override bool Init(Game _game)
        {
            game = _game;

            listOfCameras = new List<Camera>();
            listOfDrawables = new List<IDrawable>();

            InitializeGraphicStyle(game.Content);
            
            labyrinth = new Labyrinth(GDevice, 20, 20, quadShader, wallColor, wallNormal, groundColor, groundNormal, doorColor, doorNormal);

            player1 = new Player(game.Content, GDevice, player1model, new Vector3(-2000.0f, 0.0f, 500.0f + 1000 * (labyrinth.Width / 2f - 1)), Keys.Up, Keys.Down, Keys.Left, Keys.Right, Keys.RightControl);
            player2 = new Player(game.Content, GDevice, player2model, new Vector3(-2000.0f, 0.0f, 500.0f + 1000 * (labyrinth.Width / 2f)), Keys.W, Keys.S, Keys.A, Keys.D, Keys.LeftControl);
            player1.ScaleMatrix = Matrix.CreateScale(player1scale);
            player2.ScaleMatrix = Matrix.CreateScale(player2scale);
            player1.minimumAltitude = upgogopl1;
            player2.minimumAltitude = upgogopl2;

            coockie = new Coockie(game.Content.Load<Model>("Models/Kolac"), labyrinth, new Vector3(1000 * labyrinth.Width / 2, 0.0f, 1000 * labyrinth.Height / 2));
            cupavci = new Cupavci(game.Content.Load<Model>("Models/Cupavci"), labyrinth, new Vector3(1000 * labyrinth.Width + 800, 0.0f, 1000 * labyrinth.Height / 2));


            listOfDrawables.Add(player1);
            listOfDrawables.Add(player2);
            listOfDrawables.Add(labyrinth);

            listOfDrawables.Add(coockie);
            listOfDrawables.Add(cupavci);

            listOfAI = generateListOfAI(game.Content.Load<Model>("Models/Ghost"), 3);
            listOfDrawables.AddRange(listOfAI);

            listOfPowerUps = generateListOfPowerUps(game.Content.Load<Model>("Models/PowerUp"), 20);

            cameraPlayer1 = new Camera(viewportPlayer1, new Vector3(0.0f, 600.0f, 1200.0f), new Vector3(0.0f, 300.0f, 0.0f), 10.0f, 100000.0f, player1);
            cameraPlayer2 = new Camera(viewportPlayer2, new Vector3(0.0f, 600.0f, 1200.0f), new Vector3(0.0f, 300.0f, 0.0f), 10.0f, 100000.0f, player2);

            listOfCameras.Add(cameraPlayer1);
            listOfCameras.Add(cameraPlayer2);

            Texture2D hudTexture = game.Content.Load<Texture2D>("Textures/Hud");
            SpriteFont spriteFont = game.Content.Load<SpriteFont>("Fonts/Font1");

            hud = new Hud(hudTexture, spriteFont);

            Texture2D playerMiniMap = game.Content.Load<Texture2D>("Textures/PointOnMiniMap");
            Texture2D mapEdgeTexture = game.Content.Load<Texture2D>("Textures/MapEdge");
            Texture2D whiteTexture = game.Content.Load<Texture2D>("Textures/WhiteTexture");

            miniMap = new MiniMap(labyrinth, playerMiniMap, mapEdgeTexture, whiteTexture, player1, player2);

            spriteBatch = new SpriteBatch(GDevice);

            //LoadSounds();
            //LoadMusic();

            cookiePickedUp = false;
            almostThere = false;
            gotToTheEnd = false;

            return base.Init(game);
        }

        public void ChangePlayerModel(Character p1, Character p2)
        {
            switch (p1)
            {
                case Character.Koko:
                    player1model = "Models/Koko";
                    player1scale = 20f;
                    player1.minimumAltitude = -20.0f;
                    upgogopl1 = 20;
                    player1.offset = new Vector3(0, 20, 0);
                    break;
                case Character.Krakow:
                    player1model = "Models/Krakow";
                    player1scale = 22f;
                    upgogopl1 = 230;
                    break;
                case Character.Robo:
                    player1model = "Models/Robo";
                    player1scale = 250f;
                    player1.minimumAltitude = -80.0f;
                    upgogopl1 = -80;
                    break;
            }
            
            switch (p2)
            {
                case Character.Koko:
                    player2model = "Models/Koko";
                    player2scale = 20f;
                    upgogopl2 = 20.0f;
                    break;
                case Character.Krakow:
                    player2model = "Models/Krakow";
                    player2scale = 22f;
                    upgogopl2 = 230;
                    break;
                case Character.Robo:
                    player2model = "Models/Robo";
                    player2scale = 250f;
                    upgogopl2 = -80.0f;
                    break;
            }
        }

        private List<PowerUp> generateListOfPowerUps(Model model, int count)
        {
            List<PowerUp> listOfPowerUps = new List<PowerUp>();
            Random random = new Random();

            List<Vector3> listOfPositions = new List<Vector3>();
            for (int i = 0; i < count; i++)
            {
                int randPathNum = random.Next(0, labyrinth.ListOfPathElements.Count());

                Vector2 pos = labyrinth.ListOfPathElements[randPathNum].Beginig;
                Vector2 dir = labyrinth.ListOfPathElements[randPathNum].End - labyrinth.ListOfPathElements[randPathNum].Beginig;

                int lenght = (int)dir.Length();
                dir.Normalize();
                pos = pos + dir * random.Next(0, lenght + 1);

                Vector3 position = new Vector3(pos.X, 0.8f, pos.Y) * 1000;

                if (!listOfPositions.Contains(position))
                {
                    listOfPositions.Add(position);
                }
                else
                {
                    continue;
                }

                PowerUpType typeOfPowerUp = (PowerUpType)(random.Next(0, 5));
                Texture2D powerUpTexture = game.Content.Load<Texture2D>("PowerUps/" + Enum.GetName(typeof(PowerUpType), typeOfPowerUp));

                PowerUp powerUp = new PowerUp(model, powerUpTexture, typeOfPowerUp, position);
                listOfPowerUps.Add(powerUp);

            }

            return listOfPowerUps;
        }
        private List<AI> generateListOfAI(Model model, int count)
        {
            List<AI> listOfAI = new List<AI>();
            Random random = new Random();
            for (int i = 0; i < count; i++)
            {
                int position = random.Next(0, labyrinth.ListOfNodeElements.Count());
                AI ai = new AI(model, labyrinth, position);
                listOfAI.Add(ai);
            }

            return listOfAI;
        }
        private void InitializeGraphicStyle(ContentManager content)
        {
            if (graphicStyle == GraphicStyle.Dungeon)
            {
                wallColor = game.Content.Load<Texture2D>("Textures/WhiteWallColor");
                wallNormal = game.Content.Load<Texture2D>("Textures/NormalMap4");
                groundColor = game.Content.Load<Texture2D>("Textures/RedBallsFloorColor2");
                groundNormal = game.Content.Load<Texture2D>("Textures/NormalMap1");
            }

            if (graphicStyle == GraphicStyle.Red)
            {
                wallColor = game.Content.Load<Texture2D>("Textures/RedBallsWallColor2");
                wallNormal = game.Content.Load<Texture2D>("Textures/NormalMap3");
                groundColor = game.Content.Load<Texture2D>("Textures/RedBallsFloorColor2");
                groundNormal = game.Content.Load<Texture2D>("Textures/NormalMap1");
            }

            if (graphicStyle == GraphicStyle.Green)
            {
                wallColor = game.Content.Load<Texture2D>("Textures/GrassColor");
                wallNormal = game.Content.Load<Texture2D>("Textures/NormalMap4");
                groundColor = game.Content.Load<Texture2D>("Textures/GroundColor");
                groundNormal = game.Content.Load<Texture2D>("Textures/NormalMap5");
            }

            if (graphicStyle == GraphicStyle.Blue)
            {
                wallColor = game.Content.Load<Texture2D>("Textures/WhiteWallColor");
                wallNormal = game.Content.Load<Texture2D>("Textures/NormalMap4");
                groundColor = game.Content.Load<Texture2D>("Textures/RedBallsFloorColor2");
                groundNormal = game.Content.Load<Texture2D>("Textures/NormalMap1");
            }

            quadShader = game.Content.Load<Effect>("Shaders/ShaderNormalMapping");
            doorColor = game.Content.Load<Texture2D>("Textures/Gate");
            doorNormal = game.Content.Load<Texture2D>("Textures/NormalMap1");
        }
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        private void LoadSounds()
        {
            // sounds load
            //soundNoJump = game.Content.Load<SoundEffect>("Sounds/NoJump");
            //soundNoJumpInstance = soundNoJump.CreateInstance();
            //soundLightsOut = game.Content.Load<SoundEffect>("Sounds/LightsOut");
            //soundLightsOutInstance = soundLightsOut.CreateInstance();
            //soundLightsOut2 = soundLightsOut = game.Content.Load<SoundEffect>("Sounds/LightsOut2");
            //soundLightsOut2Instance = soundLightsOut2.CreateInstance();
            //soundNoMove = game.Content.Load<SoundEffect>("Sounds/NoMove");
            //soundNoMoveInstance = soundNoMove.CreateInstance();
            //soundCompass = game.Content.Load<SoundEffect>("Sounds/Compass");
            //soundCompassInstance = soundCompass.CreateInstance();
            //soundConfused = game.Content.Load<SoundEffect>("Sounds/WaitWhat");
            //soundConfusedInstance = soundConfused.CreateInstance();
            //soundGameEnd = game.Content.Load<SoundEffect>("Sounds/GameEnd");
            //soundGameEndInstance = soundGameEnd.CreateInstance();

        }
        Random random = new Random();
        private void LoadMusic()
        {
            //musicgame11 = game.Content.Load<SoundEffect>("Music/Game11");
            //musicgame11Instance = musicgame11.CreateInstance();
            //musicgame12 = game.Content.Load<SoundEffect>("Music/Game12");
            //musicgame12Instance = musicgame12.CreateInstance();
            //musicgame21 = game.Content.Load<SoundEffect>("Music/Game21");
            //musicgame21Instance = musicgame21.CreateInstance();
            //musicgame31 = game.Content.Load<SoundEffect>("Music/Game31");
            //musicgame31Instance = musicgame31.CreateInstance();
            //musicStolen1 = game.Content.Load<SoundEffect>("Music/Stolen1");
            //musicStolen1Instance = musicStolen1.CreateInstance();
            //musicStolen2 = game.Content.Load<SoundEffect>("Music/Stolen2");
            //musicStolen2Instance = musicStolen2.CreateInstance();
            int choice = random.Next(0, 3);
            switch (choice)
            {
                case 0:
                    musicGameQueue.Enqueue(musicgame11Instance);
                    musicGameQueue.Enqueue(musicgame12Instance);
                    musicStolenQueue.Enqueue(musicStolen1Instance);
                    break;
                case 1:
                    musicGameQueue.Enqueue(musicgame21Instance);
                    musicStolenQueue.Enqueue(musicStolen1Instance);
                    break;
                case 2:
                    musicGameQueue.Enqueue(musicgame31Instance);
                    musicGameQueue.Enqueue(musicgame12Instance);
                    musicStolenQueue.Enqueue(musicStolen2Instance);
                    break; 
            }
                
            
        }


        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        public override void Shutdown()
        {
            // TODO: Unload any non ContentManager content here
        }
        #endregion
        #region Update

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            lastKeyboardState = currentKeyboardState;
            currentKeyboardState = Keyboard.GetState();

            if (currentKeyboardState.IsKeyDown(Keys.Escape))
            {
                //musicGameQueue.Peek().Stop();
                //musicStolenQueue.Peek().Stop();
                GDevice.Viewport = new Viewport(0, 0, GDevice.ScissorRectangle.Width, GDevice.ScissorRectangle.Height);
                ScreenManager.SCREEN_MANAGER.goto_screen("main");
            }

            if (currentKeyboardState.IsKeyDown(Keys.Space))
            {
                if (labyrinth.ListOfWallElements[labyrinth.ListOfWallElements.Count - 1].WallType == WalllType.startWallSegment)
                {
                    labyrinth.ListOfWallElements.RemoveAt(labyrinth.ListOfWallElements.Count - 1);
                }
            }


            CollisionDetection.ClearLabyrinthWalls();
            CollisionDetection.SetLabyrinthWalls(labyrinth);

            player1.Update(gameTime, cameraPlayer1, player2, listOfAI);
            player2.Update(gameTime, cameraPlayer2, player1, listOfAI);


            foreach (AI ai in listOfAI)
            {
                ai.Update(gameTime);
            }

            foreach (PowerUp powerUp in listOfPowerUps)
            {
                powerUp.Update(gameTime);
            }

            cameraPlayer1.Update(gameTime);
            cameraPlayer2.Update(gameTime);

            cameraCollisionDetectionPravac();
            //cameraCollisionDetectionRotacija();

            powerUpCollisionDetection(gameTime);
            if (cookieCollisionDetection())
            {
                if (!almostThere)
                {
                    almostThere = true;
                    if (labyrinth.ListOfWallElements[labyrinth.ListOfWallElements.Count - 1].WallType == WalllType.exitWallSegment)
                    {
                        labyrinth.ListOfWallElements.RemoveAt(labyrinth.ListOfWallElements.Count - 1);
                    }
                }
            }

            if (player1.cookiedPickedUp)
            {
                coockie.Position = player1.Position + new Vector3(100, 200, 0);
                cookiePickedUp = true;
            }
            if (player2.cookiedPickedUp)
            {
                coockie.Position = player2.Position + new Vector3(100, 200, 0);
                cookiePickedUp = true;
            }

            cupavciCollisionDetection();

            if (gotToTheEnd)
            {
                coockie.Position = cupavci.Position + new Vector3(100, 500, 0);
                //if (PlayEndSound())
                //{
                    GDevice.Viewport = new Viewport(0, 0, GDevice.ScissorRectangle.Width, GDevice.ScissorRectangle.Height);
                    ScreenManager.SCREEN_MANAGER.goto_screen("main");
                //}
            }

            //PlayMusic();

            base.Update(gameTime);
        }
        
        private void cameraCollisionDetectionPravac()
        {
            Vector3 directionCamera1 = cameraPlayer1.OriginalPosition - cameraPlayer1.LookAt;
            directionCamera1.Normalize();
            Ray rayCamera1 = new Ray(cameraPlayer1.LookAt, directionCamera1);

            Vector3 directionCamera2 = cameraPlayer2.OriginalPosition - cameraPlayer2.LookAt;
            directionCamera2.Normalize();
            Ray rayCamera2 = new Ray(cameraPlayer2.LookAt, directionCamera2);

            float? distanceCamera1;
            float? distanceCamera2;

            bool collisionDetectedCamera1 = false;
            bool collisionDetectedCamera2 = false;
            foreach (WallElement wall in labyrinth.ListOfWallElements)
            {
                distanceCamera1 = rayCamera1.Intersects(wall.BoundingBox);
                if (distanceCamera1 != null && distanceCamera1 < cameraPlayer1.LookAtCameraDistance)
                {
                    cameraPlayer1.DesiredPositionOffset = cameraPlayer1.OriginalPositionOffset + (0.1f + 1 - (float)distanceCamera1 / cameraPlayer1.LookAtCameraDistance) * cameraPlayer1.CameraDirection;
                    collisionDetectedCamera1 = true;
                }

                distanceCamera2 = rayCamera2.Intersects(wall.BoundingBox);
                if (distanceCamera2 != null && distanceCamera2 < cameraPlayer2.LookAtCameraDistance)
                {
                    cameraPlayer2.DesiredPositionOffset = cameraPlayer2.OriginalPositionOffset + (0.1f + 1 - (float)distanceCamera2 / cameraPlayer2.LookAtCameraDistance) * cameraPlayer2.CameraDirection;
                    collisionDetectedCamera2 = true;
                }
            }

            if (!collisionDetectedCamera1)
            {
                cameraPlayer1.DesiredPositionOffset = cameraPlayer1.OriginalPositionOffset;
            }
            cameraPlayer1.collisionDetected = collisionDetectedCamera1;

            if (!collisionDetectedCamera2)
            {
                cameraPlayer2.DesiredPositionOffset = cameraPlayer2.OriginalPositionOffset;
            }
            cameraPlayer2.collisionDetected = collisionDetectedCamera2;
        }
        private void cameraCollisionDetectionRotacija()
        {
            Vector3 directionCamera1 = cameraPlayer1.OriginalPosition - cameraPlayer1.LookAt;
            directionCamera1.Normalize();
            Ray rayCamera1 = new Ray(cameraPlayer1.LookAt, directionCamera1);

            Vector3 directionCamera2 = cameraPlayer2.OriginalPosition - cameraPlayer2.LookAt;
            directionCamera2.Normalize();
            Ray rayCamera2 = new Ray(cameraPlayer2.LookAt, directionCamera2);

            float? distanceCamera1;
            float? distanceCamera2;

            Vector3 positionOffsetCamera1;
            Vector3 positionOffsetCamera2;

            bool collisionDetectedCamera1 = false;
            bool collisionDetectedCamera2 = false;
            foreach (WallElement wall in labyrinth.ListOfWallElements)
            {
                distanceCamera1 = rayCamera1.Intersects(wall.BoundingBox);
                if (distanceCamera1 != null && distanceCamera1 < cameraPlayer1.LookAtCameraDistance)
                {
                    positionOffsetCamera1 = cameraPlayer1.OriginalPositionOffset + (1 - (float)distanceCamera1 / cameraPlayer1.LookAtCameraDistance) * cameraPlayer1.CameraDirection;
                    positionOffsetCamera1.Y = (float)Math.Sqrt(cameraPlayer1.CameraDirection.Length() * cameraPlayer1.LookAtCameraDistance -
                        positionOffsetCamera1.X * positionOffsetCamera1.X - positionOffsetCamera1.Z * positionOffsetCamera1.Z);

                    cameraPlayer1.DesiredPositionOffset = positionOffsetCamera1;
                    collisionDetectedCamera1 = true;
                }

                distanceCamera2 = rayCamera2.Intersects(wall.BoundingBox);
                if (distanceCamera2 != null && distanceCamera2 < cameraPlayer2.LookAtCameraDistance)
                {
                    positionOffsetCamera2 = cameraPlayer2.OriginalPositionOffset + (1 - (float)distanceCamera2 / cameraPlayer2.LookAtCameraDistance) * cameraPlayer2.CameraDirection;
                    positionOffsetCamera2.Y = (float)Math.Sqrt(cameraPlayer2.CameraDirection.Length() * cameraPlayer2.LookAtCameraDistance -
                        positionOffsetCamera2.X * positionOffsetCamera2.X - positionOffsetCamera2.Z * positionOffsetCamera2.Z);

                    cameraPlayer2.DesiredPositionOffset = positionOffsetCamera2;
                    collisionDetectedCamera2 = true;
                }
            }

            if (!collisionDetectedCamera1)
            {
                cameraPlayer1.DesiredPositionOffset = cameraPlayer1.OriginalPositionOffset;
            }
            cameraPlayer1.collisionDetected = collisionDetectedCamera1;

            if (!collisionDetectedCamera2)
            {
                cameraPlayer2.DesiredPositionOffset = cameraPlayer2.OriginalPositionOffset;
            }
            cameraPlayer2.collisionDetected = collisionDetectedCamera2;
        }
        private void powerUpCollisionDetection(GameTime gameTime)
        {
            BoundingBox player1BoundingBox = new BoundingBox(player1.Position - new Vector3(50, 50, 50), player1.Position + new Vector3(50, 50, 50));
            BoundingBox player2BoundingBox = new BoundingBox(player2.Position - new Vector3(50, 50, 50), player2.Position + new Vector3(50, 50, 50));

            PowerUp deletePowerUpP1 = null;
            PowerUp deletePowerUpP2 = null;

            double rnd = 2;
            Random random = new Random();
            foreach (PowerUp powerUp in listOfPowerUps)
            {
                if (player1BoundingBox.Intersects(powerUp.BoundingBox))
                {
                    rnd = random.NextDouble();
                    if (rnd >= 0.5 && rnd <= 1)
                        player1.AddPowerUp(powerUp);
                    else
                        player2.AddPowerUp(powerUp);

                    deletePowerUpP1 = powerUp;
                    //PlayPowerUpSound(powerUp.TypeOfPowerUp);
                    continue;
                }

                if (player2BoundingBox.Intersects(powerUp.BoundingBox))
                {
                    rnd = random.NextDouble();
                    if (rnd >= 0.5 && rnd <= 1)
                        player2.AddPowerUp(powerUp);
                    else
                        player1.AddPowerUp(powerUp);

                    deletePowerUpP2 = powerUp;
                    //PlayPowerUpSound(powerUp.TypeOfPowerUp);
                    break;

                }
            }

            if (deletePowerUpP1 != null)
            {
                listOfPowerUps.Remove(deletePowerUpP1);
            }

            if (deletePowerUpP2 != null)
            {
                listOfPowerUps.Remove(deletePowerUpP2);
            }
        }

        private bool cookieCollisionDetection()
        {
            BoundingBox player1BoundingBox = new BoundingBox(player1.Position - new Vector3(50, 50, 50), player1.Position + new Vector3(50, 50, 50));
            BoundingBox player2BoundingBox = new BoundingBox(player2.Position - new Vector3(50, 50, 50), player2.Position + new Vector3(50, 50, 50));

            if (player1BoundingBox.Intersects(coockie.box))
            {
                player1.cookiedPickedUp = true;
                return true;
            }
            if (player2BoundingBox.Intersects(coockie.box))
            {
                player2.cookiedPickedUp = true;
                return true;
            }
            return false;
        }

        private void cupavciCollisionDetection()
        {
            BoundingBox player1BoundingBox = new BoundingBox(player1.Position - new Vector3(50, 50, 50), player1.Position + new Vector3(50, 50, 50));
            BoundingBox player2BoundingBox = new BoundingBox(player2.Position - new Vector3(50, 50, 50), player2.Position + new Vector3(50, 50, 50));

            if (player1BoundingBox.Intersects(cupavci.box))
            {
                if (player1.cookiedPickedUp)
                {
                    gotToTheEnd = true;
                    soundGameEndInstance.Volume = 0.2f * soundIntensity;
                    //soundGameEndInstance.Play();
                }
            }
            if (player2BoundingBox.Intersects(cupavci.box))
            {
                if (player2.cookiedPickedUp)
                {
                    gotToTheEnd = true;
                    soundGameEndInstance.Volume = 0.2f * soundIntensity;
                    //soundGameEndInstance.Play();
                }
            }
        }

        private void PlayPowerUpSound(PowerUpType powerUpType)
        {
            if (powerUpType == PowerUpType.Skok)
            {
                soundNoJumpInstance.Volume = 0.2f * soundIntensity;
                soundNoJumpInstance.Play();
            }
            if (powerUpType == PowerUpType.Zarulja)
            {
                soundLightsOutInstance.Volume = 0.2f * soundIntensity;
                soundLightsOutInstance.Play();
                soundLightsOut2Instance.Volume = 0.2f * soundIntensity;
                soundLightsOut2Instance.Play();
            }
            if (powerUpType == PowerUpType.Cipela)
            {
                soundNoMoveInstance.Volume = 0.2f * soundIntensity;
                soundNoMoveInstance.Play();
            }
            if (powerUpType == PowerUpType.Upitnik)
            {
                soundConfusedInstance.Volume = 0.2f * soundIntensity;
                soundConfusedInstance.Play();
            }
            if (powerUpType == PowerUpType.Kompas)
            {
                soundCompassInstance.Volume = 0.2f * soundIntensity;
                soundCompassInstance.Play();
            }
        }
        private void PlayMusic()
        {
            if (!cookiePickedUp)
            {
                if (musicGameQueue.Count != 0)
                {
                    SoundEffectInstance music = musicGameQueue.Peek();
                    if (music.State == SoundState.Stopped)
                    {
                        music = musicGameQueue.Dequeue();
                        musicGameQueue.Enqueue(music);
                        music = musicGameQueue.Peek();
                        music.Volume = 0.2f * soundIntensity;
                        music.Play();
                    }
                    else if (music.State == SoundState.Playing)
                    {
                        music.Play();
                    }
                }
            }
            else
            {
                musicGameQueue.Peek().Stop();
                if (musicStolenQueue.Count != 0)
                {
                    SoundEffectInstance music = musicStolenQueue.Peek();
                    if (music.State == SoundState.Stopped)
                    {
                        music = musicStolenQueue.Dequeue();
                        musicStolenQueue.Enqueue(music);
                        music = musicStolenQueue.Peek();
                        music.Volume = 0.2f * soundIntensity;
                        music.Play();
                    }
                    else if (music.State == SoundState.Playing)
                    {
                        music.Play();
                    }
                }
            }
        }
        private bool PlayEndSound()
        {
            musicStolenQueue.Peek().Stop();
            if (soundGameEndInstance.State == SoundState.Stopped)
                return true;                    
            soundGameEndInstance.Play();
            return false;
        }
        #endregion
        #region Draw
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Draw(GameTime gameTime)
        {
            GDevice.Clear(Color.CornflowerBlue);

            GDevice.BlendState = BlendState.Opaque;
            GDevice.DepthStencilState = DepthStencilState.Default;
            GDevice.SamplerStates[0] = SamplerState.LinearWrap;

            foreach (Camera camera in listOfCameras)
            {
                coockie.Draw(camera);
                cupavci.Draw(camera);

                foreach (IDrawable drawable in listOfDrawables)
                {
                    drawable.Draw(camera);
                }

                //potrebno je sortirati transparentne objekte po udaljenosti napram kamere
                drawTransparentObjects(camera);
                camera.Player.LightsOut(camera.Viewport);
                hud.Draw(camera);
                miniMap.Draw(camera);

                //bez ovog dolazi do nekih cudnih stvari!!

                GDevice.BlendState = BlendState.Opaque;
                GDevice.DepthStencilState = DepthStencilState.Default;
                GDevice.SamplerStates[0] = SamplerState.LinearWrap;
            }


            base.Draw(gameTime);
        }

        private void drawTransparentObjects(Camera camera)
        {
            listOfPowerUps.Sort
            ((
            delegate(PowerUp first, PowerUp second)
            {
                if ((first.Position - camera.Position).Length() > (second.Position - camera.Position).Length())
                    return -1;
                else
                    return 1;
            }
            ));

            foreach (IDrawable powerUP in listOfPowerUps)
            {
                powerUP.Draw(camera);
            }
        }
        #endregion
    }
}
